/**
 ******************************************************************************
 * @file           : bsp_log_config.h
 * @brief          : BSP Log System Configuration Template
 ******************************************************************************
 * @attention
 *
 * BSP日志系统配置模板
 * 提供统一的日志接口
 *
 ******************************************************************************
 */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __BSP_LOG_CONFIG_H
#define __BSP_LOG_CONFIG_H

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include <stdio.h>

/* Exported types ------------------------------------------------------------*/

/**
 * @brief 日志级别枚举
 */
typedef enum
{
    LOG_LEVEL_DEBUG = 0,        /*!< 调试信息 */
    LOG_LEVEL_INFO,             /*!< 一般信息 */
    LOG_LEVEL_WARNING,          /*!< 警告信息 */
    LOG_LEVEL_ERROR             /*!< 错误信息 */
} LogLevel_e;

/* Exported constants --------------------------------------------------------*/

/*============================================================================*/
/*                           日志系统选择                                      */
/*============================================================================*/

/**
 * @brief 日志系统类型
 * 0 = 禁用日志
 * 1 = 使用printf（通过串口）
 * 2 = 使用EasyLogger
 * 3 = 自定义日志系统
 */
#define LOG_SYSTEM_TYPE         1

/**
 * @brief 当前日志级别
 */
#define LOG_CURRENT_LEVEL       LOG_LEVEL_DEBUG

/**
 * @brief 日志颜色支持
 */
#define LOG_COLOR_ENABLE        1

/**
 * @brief 时间戳支持
 */
#define LOG_TIMESTAMP_ENABLE    1

/**
 * @brief 文件名和行号
 */
#define LOG_FILE_LINE_ENABLE    1

/* Exported macro ------------------------------------------------------------*/

/*============================================================================*/
/*                           颜色定义（ANSI转义码）                            */
/*============================================================================*/

#if (LOG_COLOR_ENABLE == 1)
    #define LOG_COLOR_NONE      "\033[0m"       /* 默认色 */
    #define LOG_COLOR_RED       "\033[31m"      /* 红色 */
    #define LOG_COLOR_GREEN     "\033[32m"      /* 绿色 */
    #define LOG_COLOR_YELLOW    "\033[33m"      /* 黄色 */
    #define LOG_COLOR_BLUE      "\033[34m"      /* 蓝色 */
    #define LOG_COLOR_MAGENTA   "\033[35m"      /* 紫色 */
    #define LOG_COLOR_CYAN      "\033[36m"      /* 青色 */
    #define LOG_COLOR_WHITE     "\033[37m"      /* 白色 */
#else
    #define LOG_COLOR_NONE      ""
    #define LOG_COLOR_RED       ""
    #define LOG_COLOR_GREEN     ""
    #define LOG_COLOR_YELLOW    ""
    #define LOG_COLOR_BLUE      ""
    #define LOG_COLOR_MAGENTA   ""
    #define LOG_COLOR_CYAN      ""
    #define LOG_COLOR_WHITE     ""
#endif

/*============================================================================*/
/*                           日志宏定义                                        */
/*============================================================================*/

#if (LOG_SYSTEM_TYPE == 0)
    /* 禁用日志 */
    #define log_d(fmt, ...)
    #define log_i(fmt, ...)
    #define log_w(fmt, ...)
    #define log_e(fmt, ...)

#elif (LOG_SYSTEM_TYPE == 1)
    /* 使用printf */
    
    #if (LOG_FILE_LINE_ENABLE == 1)
        #define LOG_FORMAT(level, color, fmt) \
            color "[" level "] %s:%d: " fmt LOG_COLOR_NONE "\r\n"
        
        #define LOG_PRINT(level, color, fmt, ...) \
            printf(LOG_FORMAT(level, color, fmt), __FILE__, __LINE__, ##__VA_ARGS__)
    #else
        #define LOG_FORMAT(level, color, fmt) \
            color "[" level "] " fmt LOG_COLOR_NONE "\r\n"
        
        #define LOG_PRINT(level, color, fmt, ...) \
            printf(LOG_FORMAT(level, color, fmt), ##__VA_ARGS__)
    #endif
    
    /* DEBUG级别 */
    #if (LOG_CURRENT_LEVEL <= LOG_LEVEL_DEBUG)
        #define log_d(fmt, ...)     LOG_PRINT("DEBUG", LOG_COLOR_CYAN, fmt, ##__VA_ARGS__)
    #else
        #define log_d(fmt, ...)
    #endif
    
    /* INFO级别 */
    #if (LOG_CURRENT_LEVEL <= LOG_LEVEL_INFO)
        #define log_i(fmt, ...)     LOG_PRINT("INFO ", LOG_COLOR_GREEN, fmt, ##__VA_ARGS__)
    #else
        #define log_i(fmt, ...)
    #endif
    
    /* WARNING级别 */
    #if (LOG_CURRENT_LEVEL <= LOG_LEVEL_WARNING)
        #define log_w(fmt, ...)     LOG_PRINT("WARN ", LOG_COLOR_YELLOW, fmt, ##__VA_ARGS__)
    #else
        #define log_w(fmt, ...)
    #endif
    
    /* ERROR级别 */
    #if (LOG_CURRENT_LEVEL <= LOG_LEVEL_ERROR)
        #define log_e(fmt, ...)     LOG_PRINT("ERROR", LOG_COLOR_RED, fmt, ##__VA_ARGS__)
    #else
        #define log_e(fmt, ...)
    #endif

#elif (LOG_SYSTEM_TYPE == 2)
    /* 使用EasyLogger */
    #include "elog.h"
    
    #define log_d(fmt, ...)     log_d(fmt, ##__VA_ARGS__)
    #define log_i(fmt, ...)     log_i(fmt, ##__VA_ARGS__)
    #define log_w(fmt, ...)     log_w(fmt, ##__VA_ARGS__)
    #define log_e(fmt, ...)     log_e(fmt, ##__VA_ARGS__)

#else
    /* 自定义日志系统（需要用户实现） */
    extern void custom_log(LogLevel_e level, const char *fmt, ...);
    
    #define log_d(fmt, ...)     custom_log(LOG_LEVEL_DEBUG, fmt, ##__VA_ARGS__)
    #define log_i(fmt, ...)     custom_log(LOG_LEVEL_INFO, fmt, ##__VA_ARGS__)
    #define log_w(fmt, ...)     custom_log(LOG_LEVEL_WARNING, fmt, ##__VA_ARGS__)
    #define log_e(fmt, ...)     custom_log(LOG_LEVEL_ERROR, fmt, ##__VA_ARGS__)
#endif

/*============================================================================*/
/*                           断言宏                                            */
/*============================================================================*/

#define LOG_ASSERT(expr)                        \
    do {                                        \
        if (!(expr)) {                          \
            log_e("ASSERT FAILED: %s", #expr);  \
            while(1);                           \
        }                                       \
    } while(0)

/* Exported variables --------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/

/**
 * @brief       设置日志级别
 */
void log_set_level(LogLevel_e level);

/**
 * @brief       获取当前日志级别
 */
LogLevel_e log_get_level(void);

#ifdef __cplusplus
}
#endif

#endif /* __BSP_LOG_CONFIG_H */
